﻿package Game{
	import Game.DisplaySystem.DisplayManager;
	import Game.LogicSystem.ActionManager;
	import Game.LogicSystem.ObjectManager;
	import Game.MapSystem.MapManager;
	import Game.MouseSystem.MouseManager;
	import Game.PlaySystem.PlayManager;
	import Game.Utils.FileLoader;
	import Game.Utils.T;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	
	/**
	 * @class GameMaster
	 * @author Mini_Douze
	 * Front Controller for GameInstance
	 * 
	 * 
	 */
	 public class GameMaster extends MovieClip{
		//Fichier de partie envoyé par la MainClass lors de la créatio d'une partie
		private var gameFile:String;
		//Dossier contenant les Donées
		private var gameDatas:String;
		
		//Informations stockées sur la partie:
		private var gameName:String;
		private var gamePlayers:Array;//Tableau de joueur chaque joueur est représenté par un tableau avec :
									  //[0]->nom du joueur;[1]->human(bool);
									  
		private var gameMapsFiles:Array;//[0]->GroundMapAdress; [1]->ObjectsMapAdress;
		private var gameStateFile:String;//url du fichier d'enregistrement de l'etat de la partie (etat courant)
		
		private var interfaceInfos:Array= new Array();// Tableau contenant les parametres de l'interface : [0]type [1]fichier
		private var interfaceObject:*;
		
		//Variable servant l'enregistrement de l'etat de jeu;
		//Permettra de gerer les actions et les enterFrameRefresh à effectuer
		//exemple: 	en PLAYING_STATE le joueur aura la main, mais au passage en PAUSE_STATE les écouteurs seront 
		// 			tous supprimés et pendant le ENNEMY_PLAYING_STATE les clics seront interdits mais pas le scrolling
		private var gameCurrentState:int;
		public function setState(_state:int):void{
			if(_state > 0){
				gameCurrentState = _state;
			}
		}
		//Variable de comptage des Frames
		//incrementé a chaque Frame.
		//Sert pour la gestion generale du jeu ->est affiché dans l'interface Debug(DebugScreen);
		private var gameCurrentFrame:int;
		
		//Liste des Etats du moteur de jeu (sous forme de CONST pour eviter les switch sur String beaucoup plus longs)
		public const INIT_STATE:int = 0;
		public const LOADING_STATE	:int = 1;
		public const PLAYING_STATE	:int = 2;
		public const WAITING_STATE	:int = 3;
		public const PAUSE_STATE	:int = 4;
		
		
		//---------------------------
		//Manager static
		//public static var s_XmlManager:XmlManager = new XmlManager();
		
		//Managers : name m_ + manager type
		private var m_Display:DisplayManager;
		private var m_MouseM:MouseManager;
		private var m_MapM:MapManager;
		public var m_PlayM:PlayManager;
		private var m_ActionM:ActionManager;
		public var m_ObjectM:ObjectManager;
		
		
		/**
		 * @function Constructor
		 * @param : GameFile Adress:String (XML format)
		 * 
		 * */
		 public function GameMaster(_gameFileAdress:String):void{
			gameCurrentState = INIT_STATE;
			gameCurrentFrame = 0;
			
			gameDatas = _gameFileAdress;
			gameFile = gameDatas+"xml/game.xml";
			
			gamePlayers = new Array();
			gameMapsFiles = new Array();
			
			
			m_Display = new DisplayManager(this);
			m_MouseM = new MouseManager(this,m_Display.world);
			m_MapM = new MapManager(this,m_Display);
			m_PlayM = new PlayManager(this);
			m_ActionM= new ActionManager(this,m_Display);
			m_ObjectM = new ObjectManager(this,m_Display,m_ActionM);
			
			addEventListener( Event.ENTER_FRAME, refreshGame);
			
			preloadGame();
		}
		private var firstTimeState:Boolean;
		private var tempState:int=0;
		
		private function refreshGame(_evt:Event):void{
			gameCurrentFrame ++; // incrémentation de la variable currentFrame
			
			if(gameCurrentState == tempState){
				firstTimeState = false
			}else{
				firstTimeState=true;
				//T.Trace('firstTime CurrentState :'+gameCurrentState);
				} 
			switch (gameCurrentState){
				case INIT_STATE:
					return;
				break;
				case LOADING_STATE:
				
				break;
				case WAITING_STATE:
					// en attente d'un eventuel autre joueur ou IA
				break;
				case PLAYING_STATE:
					m_Display.onEnterFrameRefresh(gameCurrentFrame,'Playing',gamePlayers);
					gameHumanPlaying();
				break;
			}
			tempState = gameCurrentState;
		}
		//Fonctions de chargement
		private function preloadGame():void{
			setState(LOADING_STATE);
			//Attendre le loadGame() pour utiliser les informations du gameFile
			FileLoader.LoadObject(gameFile,saveGameFile,'xml');
		}
		private function loadGame():void{
			m_PlayM.createPlayers(gamePlayers);
			m_MapM.showGroundMap(gameMapsFiles[0]);
			m_Display.loadInterface(interfaceInfos[1]);
			m_ObjectM.showObjectMap(gameMapsFiles[1]);
			
			
			
			//cette fonction changera le state -> ...
			m_PlayM.InitTurnManager(gameStateFile);
			
		}
		private function gameHumanPlaying():void{
			if(firstTimeState){
					m_MouseM.addAllListeners();
			}
		}
		
		
		//Fonction de sauvegarde des informations de la partie
		//Prends en entrée un objet Xml (le XmlDataList du fichier game.xml)
		private function saveGameFile(_datas:XML):void{
			gameName = _datas.attribute('name');
			gameStateFile = _datas.attribute('statefile');
			T.Trace (gameStateFile,1,"GameMaster");
			for each(var XmlElement:XML in  _datas.children()){//Pour chaque element XML dans le sous element
				switch(XmlElement.name().toString()){//Test du type de balise XML
					case "interface":
						interfaceInfos[0] = XmlElement.attribute('type');
						interfaceInfos[1] = gameDatas+XmlElement.attribute('file')
					break;
					case "player":
						var playerArray:Array = new Array();
						playerArray.push(XmlElement.attribute('name'));
						playerArray.push(XmlElement.attribute('human'));
						//T.Trace("player : "+playerArray.toString());
						gamePlayers.push(playerArray);
						playerArray=null;
						
						break;
					case "map":
						gameMapsFiles[0]= gameDatas+XmlElement.toString();
						//T.Trace("GroundMap : "+gameMapsFiles[0]);
						break;
					case "objectmap":
						gameMapsFiles[1]= gameDatas+XmlElement.toString();
						//T.Trace("ObjectMap : "+gameMapsFiles[1]);
						break;
				}
			}
			loadGame();
		}		
	}
}